/*
 * Copyright 2011 Helios Technologies.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.heliostech.gwt.widget.dialog.confirm;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.ImportedWithPrefix;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.heliostech.gwt.widget.dialog.base.BaseDialog;

/**
 * A BaseDialog implementation used to display action confirmation to the user.
 * A Util.getInstance method is provided to access to a convenient reusable singleton instance.
 * @author Lionel Desdier
 * @since 22 Dec. 2011
 */
public class ConfirmationDialog extends BaseDialog {
	
	public static class Util {
		private static ConfirmationDialog instance;
		public static ConfirmationDialog getInstance() {
			if(instance==null) {
				instance = GWT.create(ConfirmationDialog.class);
			}
			return instance;
		}
	}
	
	protected interface Resources extends ClientBundle {
		@Source("./dialog-confirm.png")
		ImageResource confirmIcon();		
		@Source(Style.DEFAULT_CSS)
		@CssResource.NotStrict
	    Style style();
	}
	
	@ImportedWithPrefix("helios-ConfirmationDialog")
	public interface Style extends CssResource {
		String DEFAULT_CSS = "com/heliostech/gwt/widget/dialog/confirm/ConfirmationDialog.css";
		
		String confirmDialogWidget();
		
		String msg();

		String confirmButton();
		
		String cancelButton();
		
	}
	
	private static Resources DEFAULT_RESOURCES;
	private static Resources getDefaultResources() {
		if (DEFAULT_RESOURCES == null) {
			DEFAULT_RESOURCES = GWT.create(Resources.class);
		}
		return DEFAULT_RESOURCES;
	}	
	private final Style style;
	private final Resources resources;
	private final HTML msg;
	
	private Command confirmCmd;
	private Command cancelCmd;
	
	public ConfirmationDialog() {
		this(true);
	}
	
	public ConfirmationDialog(boolean modal) {
		this(modal, getDefaultResources());
	}
	
	public ConfirmationDialog(boolean modal, ConfirmationDialog.Resources r) {
		super("", true, modal);
		this.resources = r;
		this.style = resources.style();
		this.style.ensureInjected();
		addStyleName(style.confirmDialogWidget());
		
		setDialogTitle("Action Confirmation");
		setDialogDescription("Confirm Action", 
				"Confirm your action by clicking on the [ Confirm ] button or cancel it.", resources.confirmIcon());
		setSize("30em","15em");
		msg = new HTML();
		setContent(msg);
		
		final Button confirmB = new Button("Confirm");
		confirmB.addStyleName(style.confirmButton());
		confirmB.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				execConfirm();
			}
		});
		addButton(confirmB);
		
		final Button cancelB = new Button("Cancel");
		cancelB.addStyleName(style.cancelButton());
		cancelB.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				execCancel();
			}
		});
		addButton(cancelB);
	}
	
	private void execConfirm() {
		getConfirmationCommand().execute();
		hide();
	}
	
	private void execCancel() {
		if ( cancelCmd != null ) {
			cancelCmd.execute();
		}
		hide();
	}
	
	/* (non-Javadoc)
	 * @see com.heliostech.gwt.widget.dialog.base.BaseDialog#cleanup()
	 */
	@Override
	public void cleanup() {
		super.cleanup();
		this.msg.setText("");
		this.cancelCmd = null;
		this.confirmCmd = null;
	}

	/**
	 * Set the message to be displayed as the dialog content.
	 * @param m
	 */
	public void setMessage(String m) {
		this.msg.setHTML(SafeHtmlUtils.fromSafeConstant(m));
	}

	public Command getConfirmationCommand() {
		if ( confirmCmd == null ) {
			throw new RuntimeException("Confirmation command not set.");
		}
		return confirmCmd;
	}

	public void setConfirmationCommand(Command confirmCmd) {
		this.confirmCmd = confirmCmd;
	}

	public Command getCancelCommand() {
		return cancelCmd;
	}

	public void setCancelCommand(Command cancelCmd) {
		this.cancelCmd = cancelCmd;
	}

}
